package org.infodavid.common.model.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

import org.infodavid.common.model.IGenericPropertiesMap;
import org.infodavid.common.model.IGenericProperty;

/**
 * The Class GenericPropertiesMapImpl.
 */
public class GenericPropertiesMapImpl extends AbstractBasicDataObjectImpl implements
    IGenericPropertiesMap {

	/** The Constant serialVersionUID. */
	private static final long serialVersionUID = -8115752186078367218L;

	/** The properties. */
	private List<IGenericProperty> properties;

	/*
	 * (non-Javadoc)
	 * @see org.infodavid.common.model.impl.BasicDataObjectImpl#init()
	 */
	@Override
	public void init() throws Exception {
		super.init();

		properties = new ArrayList<IGenericProperty>();
	}

	/*
	 * (non-Javadoc)
	 * @see org.infodavid.common.data.IGenericPropertiesMap#clear()
	 */
	public void clear() {
		getData().clear();
	}

	/*
	 * (non-Javadoc)
	 * @see org.infodavid.common.data.IGenericPropertiesMap#size()
	 */
	public int size() {
		return getData().size();
	}

	/**
	 * Instantiates a new generic data map impl.
	 * @throws Exception the exception
	 */
	public GenericPropertiesMapImpl() throws Exception {
		super();
	}

	/*
	 * (non-Javadoc)
	 * @see org.infodavid.common.model.IGenericPropertiesMap#addData(org.infodavid.common.model.
	 * IGenericProperty )
	 */
	@Override
	public IGenericProperty addData(final IGenericProperty value) {
		final IGenericProperty removed = removeData(value.getName());

		getData().add(value);

		return removed;
	}

	/*
	 * (non-Javadoc)
	 * @see org.infodavid.common.model.IGenericPropertiesMap#addData(java.lang.String,
	 * java.lang.String)
	 */
	public IGenericProperty addData(final String name, final String value) {
		final IGenericProperty data = instantiateData(name, value);

		getData().add(data);

		return data;
	}

	/*
	 * (non-Javadoc)
	 * @see org.infodavid.common.model.IGenericPropertiesMap#addData(java.lang.String,
	 * java.lang.String, java.lang.String)
	 */
	public IGenericProperty addData(final String name, final String type, final String value) {
		final IGenericProperty data = instantiateData(name, value);

		data.setType(type);
		getData().add(data);

		return data;
	}

	/**
	 * Instantiate data.
	 * @return the data
	 */
	public IGenericProperty instantiateData() {
		try {
			return new GenericPropertyImpl();
		}
		catch (final Exception e) {
			throw new InstantiationError(e.getMessage());
		}
	}

	/**
	 * Instantiate data.
	 * @param name the name
	 * @return the data
	 */
	public IGenericProperty instantiateData(final String name) {
		final IGenericProperty data = instantiateData();

		data.setName(name);

		return data;
	}

	/**
	 * Instantiate data.
	 * @param name the name
	 * @param value the value
	 * @return the data
	 */
	public IGenericProperty instantiateData(final String name, final String value) {
		final IGenericProperty data = instantiateData(name);

		data.setValue(value);

		return data;
	}

	/*
	 * (non-Javadoc)
	 * @see org.infodavid.common.model.IGenericPropertiesMap#removeData(java.lang.String)
	 */
	public IGenericProperty removeData(final String name) {
		final IGenericProperty result = getData(name);

		if (result != null) {
			getData().remove(result);
		}

		return result;
	}

	/*
	 * (non-Javadoc)
	 * @see org.infodavid.common.model.IGenericPropertiesMap#getData(java.lang.String)
	 */
	public IGenericProperty getData(final String name) {
		final ListIterator<IGenericProperty> ite = getData().listIterator();
		IGenericProperty result = null;

		while (result == null && ite.hasNext()) {
			result = ite.next();

			if (!result.getName().equals(name)) {
				result = null;
			}
		}

		return result;
	}

	/*
	 * (non-Javadoc)
	 * @see org.infodavid.common.model.IGenericPropertiesMap#getValue(java.lang.String)
	 */
	public String getValue(final String name) {
		final IGenericProperty value = getData(name);

		return value == null ? null : value.getValue();
	}

	/*
	 * (non-Javadoc)
	 * @see org.infodavid.common.model.IGenericPropertiesMap#getData()
	 */
	public List<IGenericProperty> getData() {
		return properties;
	}

	/*
	 * (non-Javadoc)
	 * @see org.infodavid.common.model.IGenericPropertiesMap#setData(java.util.List)
	 */
	public void setData(final List<IGenericProperty> values) {
		properties = values;
	}
}
